package com.spit.fammo.ui.frg

import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.TimeUtils
import com.kingja.loadsir.core.LoadService
import com.spit.amoeba.base.BaseFragment
import com.spit.fammo.R
import com.spit.fammo.api.UIHelper
import com.spit.fammo.bean.db.AssetBean
import com.spit.fammo.databinding.FAssetBinding
import com.spit.fammo.ext.ASSET_FAIL_PAGE
import com.spit.fammo.ext.ASSET_NOT_PAGE
import com.spit.fammo.ext.ASSET_PAGE
import com.spit.fammo.ext.ASSET_STOCK_PAGE
import com.spit.fammo.ext.SCAN_STATUS_QRCODE
import com.spit.fammo.ext.SCAN_STATUS_SCAN
import com.spit.fammo.ext.STATUSID_ASSET_2
import com.spit.fammo.ext.STATUSID_ASSET_9
import com.spit.fammo.ext.bindViewPager2
import com.spit.fammo.ext.init
import com.spit.fammo.ext.loadServiceInit
import com.spit.fammo.keyctrl.InventoryInfo
import com.spit.fammo.mar.eventViewModel
import com.spit.fammo.viewmodel.AssetModel
import com.spit.fammo.viewmodel.RfidModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.concurrent.Executors
import java.util.concurrent.locks.ReentrantLock
import kotlin.math.E

/**
 * @Author nike
 * @Date 2023/7/27 11:43
 * @Description RFID 列表
 */
class StockTakeListAssetParentFrg: BaseFragment<AssetModel, FAssetBinding>() {

    val assetModel: AssetModel by activityViewModels()

    val rfidModel: RfidModel by activityViewModels()

    lateinit var loadsir: LoadService<Any>

    //fragment集合
    var fragments: ArrayList<Fragment> = arrayListOf()

    val lock = ReentrantLock()

    override fun initView(savedInstanceState: Bundle?) {
        arguments?.let {
            mViewModel.orderId.set(it.getString("orderId"))
            mViewModel.name.set(it.getString("name"))
        }
        setToolBarTitle(getString(R.string.full_list))
        mDatabind.includeSearch.fyAdd.visibility = View.GONE

        mDatabind.viewmodel = mViewModel
        mDatabind.click = ProxyClick()
        mViewModel.openState.set(getString(R.string.start))

        //状态页配置
        loadsir = loadServiceInit(mDatabind.layout) {

        }

        //初始化viewpager2
        var bundle = Bundle()
        bundle.putString("orderId", mViewModel.orderId.get())
        bundle.putString("name", mViewModel.name.get())

        val frg1 = StockTakeAllFrg()
        frg1.arguments = bundle
        fragments.add(frg1)

        val frg2 = StockTakeStockFrg()
        frg2.arguments = bundle
        fragments.add(frg2)

        val frg3 = StockTakeNoFrg()
        frg3.arguments = bundle
        fragments.add(frg3)

        val frg4 = StockTakeFailFrg()
        frg4.arguments = bundle
        fragments.add(frg4)

        mDatabind.includeViewpager.viewPager.init(this, fragments)
        var mTitles =
            arrayListOf(
                getString(R.string.full_list),
                getString(R.string.found),
                getString(R.string.missing),
                getString(R.string.abnormal)
            )

        mDatabind.includeViewpager.magicIndicator.bindViewPager2(mDatabind.includeViewpager.viewPager, mTitles)
        mDatabind.includeViewpager.viewPager.offscreenPageLimit = mTitles.size

        lifecycle.addObserver(object : DefaultLifecycleObserver {

            override fun onPause(owner: LifecycleOwner) {
                super.onPause(owner)
                mViewModel.isOpen.set(false)
                rfidModel.isOpen.value = false
                rfidModel.epcData.value = null
                rfidModel.epcListData.value = null
                assetModel.epcListAssetUploadFailData.value = null
                assetModel.epcListAssetUploadData.value = null
                assetModel.epcAssetUploadData.value = null
            }

        })

        mDatabind.includeSearch.fyZking.setOnClickListener {
            UIHelper.startZxingAct(ASSET_PAGE)
        }

        mDatabind.includeSearch.etInput.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
                assetModel.searchTextData.value = p0.toString()
            }

            override fun afterTextChanged(p0: Editable?) {
            }
        })

    }

    override fun lazyLoadData() {
        //设置界面 加载中
//        loadsir.showLoading()
    }

    override fun createObserver() {
        super.createObserver()
        //批量更新
        rfidModel.epcListData.observe(viewLifecycleOwner, {
            if (it == null) return@observe
            lock.lock()
            try {
                mViewModel.viewModelScope.launch(Dispatchers.IO) {
                    var readTime = TimeUtils.getNowString()

                    val epcList = it.map { it.TagId }
                        .filterNotNull()
                        .toSet()
                        .toList()
                    // 在库更新
                    var beans = mViewModel.assetDao.findEpcIdList(epcList, mViewModel.orderId.get(), mViewModel.userId, ASSET_NOT_PAGE)
                    if (beans.size != 0) {
                        val list = beans.map { bean ->
                            bean.copy(
                                type = ASSET_STOCK_PAGE,
                                scanTime = readTime,
                                scanStatus = SCAN_STATUS_SCAN,
                                statusid = STATUSID_ASSET_2,
                                stockTake = true,
                                userId = mViewModel.userId,
                                companyid = mViewModel.companyID
                            )
                        }
                        mViewModel.assetDao.updateList(list)
                        assetModel.epcListAssetUploadData.postValue(list)
                        eventViewModel.playMusic.postValue(true)
                    }

                    // 异常处理
                    var listFail = mViewModel.assetDao.findEpcIdList(epcList, mViewModel.orderId.get(), mViewModel.userId)
                    val allMatchedEpcSet = (beans + listFail).map { it.epc }.toSet()
                    val finalUnmatchedEpcList = epcList.filterNot { allMatchedEpcSet.contains(it) }
                    if (finalUnmatchedEpcList.size != 0) {
                        val list = finalUnmatchedEpcList.map {
                            AssetBean().apply {
                                this.scanTime = readTime
                                this.scanStatus = SCAN_STATUS_SCAN
                                this.type = ASSET_FAIL_PAGE
                                this.statusid = STATUSID_ASSET_9
                                this.stocktakeno = mViewModel.orderId.get()
                                this.stocktakeName = mViewModel.name.get()
                                this.userId = mViewModel.userId
                                this.companyid = mViewModel.companyID
                                this.epc = it.toString()
                            }
                        }
                        mViewModel.assetDao.addAll(list)
                        assetModel.epcListAssetUploadFailData.postValue(list)
                    }
//                    LogUtils.e("识别每秒", it.size, "过滤完", epcList.size, "异常", finalUnmatchedEpcList.size)
//                    withContext(Dispatchers.Main) {
//                        mDatabind.tvText.text = "识别每秒-" + it.size +"过滤重复-" + epcList.size + "在库新加-" + beans.size + "异常新加-" + finalUnmatchedEpcList.size
//                    }
                }
            } finally {
                lock.unlock()
            }
        })

        //单个更新
        rfidModel.epcData.observe(viewLifecycleOwner, {
            if (it == null)return@observe
            it.ReadTime = TimeUtils.getNowString()
            lock.lock()
            try {
                val tagId = it.TagId
                mViewModel.viewModelScope.launch(Dispatchers.IO) {
                    var bean = mViewModel.assetDao.findEpcId(tagId, mViewModel.orderId.get(), mViewModel.userId)
                    if (bean == null){
                        bean = mViewModel.assetDao.findAssetCodeId(tagId, mViewModel.orderId.get(), mViewModel.userId)
                    }
                    if (bean != null && bean.type == ASSET_NOT_PAGE && !bean.epc.isNullOrEmpty()){
                        bean.scanTime = TimeUtils.getNowString()
                        bean.scanStatus = SCAN_STATUS_SCAN
                        bean.type = ASSET_STOCK_PAGE
                        bean.statusid = STATUSID_ASSET_2
                        bean.stockTake = true
                        bean.userId = mViewModel.userId
                        bean.companyid = mViewModel.companyID
                        mViewModel.assetDao.update(bean)
                        eventViewModel.playMusic.postValue(true)
                    }else if (bean != null && (bean.type == ASSET_FAIL_PAGE || bean.type == ASSET_STOCK_PAGE)){
                        return@launch
                    }else{
                        bean = AssetBean()
                        bean.scanTime = TimeUtils.getNowString()
                        bean.scanStatus = SCAN_STATUS_SCAN
                        bean.type = ASSET_FAIL_PAGE
                        bean.statusid = STATUSID_ASSET_9
                        bean.stocktakeno = mViewModel.orderId.get()
                        bean.stocktakeName = mViewModel.name.get()
                        bean.userId = mViewModel.userId
                        bean.companyid = mViewModel.companyID
                        bean.epc = tagId
                        mViewModel.assetDao.add(bean)
                    }
                    assetModel.epcAssetUploadData.postValue(bean)
                }
            } finally {
                lock.unlock()
            }
        })

        eventViewModel.uploadAsset.observeInFragment(this, {
            mViewModel.viewModelScope.launch(Dispatchers.IO) {
                val bean = mViewModel.assetDao.findAssetById(it.assetno, it.stocktakeno)
                if (bean != null){
                    bean.remarks = it.remarks
                    bean.statusid = it.statusid!!
                    bean.type = it.type
                    bean.stockTake = if (it.type == ASSET_STOCK_PAGE) true else false
                    bean.pic = it.imageList
                    mViewModel.assetDao.update(bean)
                    assetModel.epcAssetUploadData.postValue(bean)
                }
            }
        })

        //扫码
        eventViewModel.zkingType.observeInFragment(this, Observer {
            if (it.Type == ASSET_PAGE) {
                val info = InventoryInfo()
                info.TagId = it.text!!
                info.Rssi = "0"
                info.scanStatus = SCAN_STATUS_QRCODE
                rfidModel.epcData.value = info
            }
        })
        //手柄扫描
        rfidModel.scanData.observe(viewLifecycleOwner, {
            if (it != null && viewLifecycleOwner.lifecycle.currentState == Lifecycle.State.RESUMED) {
                it.scanStatus = SCAN_STATUS_QRCODE
                rfidModel.epcData.value = it
            }
        })

        mViewModel.uploadMainDrawer.observe(viewLifecycleOwner, {
            rfidModel.mainDrawerUploadNum.value = 0
        })
    }

    inner class ProxyClick() {

        fun onStart(){
            mViewModel.viewModelScope.launch(Dispatchers.IO) {
                val configBean = mViewModel.configDao.findFirst()
                configBean.powerType = 0
                mViewModel.configDao.update(configBean)
                mViewModel.isOpen.set(!mViewModel.isOpen.get())
                rfidModel.isOpen.postValue(mViewModel.isOpen.get())
            }
        }

        fun onConfirm(){
            if (mViewModel.isOpen.get()){
                mViewModel.isOpen.set(false)
                rfidModel.isOpen.value = false
            }
            mViewModel.onUpload(this@StockTakeListAssetParentFrg)
        }
    }

}